#ifndef KERNEL_GLOBAL_H_
#define KERNEL_GLOBAL_H_
#include "stdint.h"

/* 段选择子属性 */
#define RPL0 0
#define RPL1 1
#define RPL2 2
#define RPL3 3
#define TI_GDT 0
#define TI_LDT 1

#define SELECTOR_K_CODE    ((1 << 3) + (TI_GDT << 2) + RPL0)  // kernel代码段b1000, 0x8
#define SELECTOR_K_DATA    ((2 << 3) + (TI_GDT << 2) + RPL0)  // 数据段b10000,0x10
#define SELECTOR_K_STACK   SELECTOR_K_DATA                    // 栈段
#define SELECTOR_K_GS      ((3 << 3) + (TI_GDT << 2) + RPL0)  // 显示段b11000,0x18
// TSS段和
#define SELECTOR_TSS       ((4 << 3) + (TI_GDT << 2) + RPL0)  // TSS段b100000,0x20                                                    // 第4个是tss段, 见下
#define SELECTOR_U_CODE    ((5 << 3) + (TI_GDT << 2) + RPL3)  // user代码段b101011,0x2b
#define SELECTOR_U_DATA    ((6 << 3) + (TI_GDT << 2) + RPL3)  // 数据段b11101l,0x3b
#define SELECTOR_U_STACK   SELECTOR_U_DATA                    // 栈段

/* GDT 全局描述符属性 */
                                 // 31-14, 8位, 基地址31-14位
#define DESC_G_4KB          1    // 23G位, 用来描述段限长limit的单位, 4KB/1B
#define DESC_D_32           1    // 22D位, 用在代码段中, 1为32位, 0为16位
#define DESC_L              0    // 21L位, 0为32位, 1为64位
#define DESC_AVL            0    // 20AVL位, 给特定用户使用, cup不使用, 置0
                                 // 19-16, 4位, 段限长19-16 
#define DESC_P              1    // 15P位, 段存在标志, 1表示存在内存中
#define DESC_DPL0           0    // 14-13DPL位, 描述符特权级
#define DESC_DPL1           1
#define DESC_DPL2           2
#define DESC_DPL3           3
#define DESC_S_CODE         1    // 12S位, 描述符类型, 1代码,数据; 0系统
#define DESC_S_DATA         1
#define DESC_S_SYS          0    // 系统段: 局部描述表的段描述, 各种门描述符, TSS描述符
                                 // 11-8, 4TYPE位
#define DESC_TYPE_DATA      2    // xewa=0010, x不可执行, e向上拓展, w可写, a末访问. a由cpu设置
#define DESC_TYPE_CODE      8    // xcra=1000, x可执行, c非依从, r不可读, a末访问 
#define DESC_TYPE_TSS       9    // 10B1, B位表示busy, 1忙, 0闲. CPU维护, 防止任务自己调用自己

#define GDT_ATTR_HIGH \
((DESC_G_4KB << 7) + (DESC_D_32 << 6) + (DESC_L << 5) + (DESC_AVL << 4))
#define GDT_CODE_ATTR_LOW_DPL3 \
((DESC_P << 7) + (DESC_DPL3 << 5) + (DESC_S_CODE << 4) + DESC_TYPE_CODE)
#define GDT_DATA_ATTR_LOW_DPL3 \
((DESC_P << 7) + (DESC_DPL3 << 5) + (DESC_S_DATA << 4) + DESC_TYPE_DATA)

/* idt 中断描述符属性 */
#define IDT_DESC_P          1    // P, 段存在标志, 1表示存在内存中
#define IDT_DESC_DPL0       0
#define IDT_DESC_DPL3       3
#define IDT_DESC_32_TYPE    0xE  // 中断门type, 0111

#define IDT_DESC_ATTR_DPL0 \
    ((IDT_DESC_P<<7) + (IDT_DESC_DPL0<<5) + IDT_DESC_32_TYPE)
#define IDT_DESC_ATTR_DPL3 \
    ((IDT_DESC_P<<7) + (IDT_DESC_DPL3<<5) + IDT_DESC_32_TYPE)

/* tss 描述符属性 */
#define TSS_DESC_D          0
#define TSS_DESC_G          1    // G位, 用来描述TSS是否有io位图, 1无, 0有
#define TSS_DESC_L          DESC_L
#define TSS_DESC_AVL        DESC_AVL
#define TSS_DESC_P          DESC_P
#define TSS_DESC_DPL0       DESC_DPL0

#define TSS_ATTR_HIGH \
((TSS_DESC_G << 7) + (TSS_DESC_D << 6) + (TSS_DESC_L << 5) + (TSS_DESC_AVL << 4) + 0x0)
#define TSS_ATTR_LOW \
((TSS_DESC_P << 7) + (TSS_DESC_DPL0 << 5) + (DESC_S_SYS << 4) + DESC_TYPE_TSS)

/* GDT中描述符的结构*/
struct gdt_desc {
    uint16_t limit_low_word;
    uint16_t base_low_word;
    uint8_t base_middle_byte;
    uint8_t attr_low_byte;
    uint8_t limit_high_attr_high;
    uint8_t base_high_byte;
};
/* EFLAGS */
#define EFLAGS_MBS (1<<1)
#define EFLAGS_IF_1 (1<<9)
#define EFLAGS_IF_0 0
#define EFLAGS_IOPL_3 (3 << 12)
#define EFLAGS_IOPL_0 (0 << 12)

/* 进程 */
#define DIV_ROUND_UP(X, STEP) ((X+STEP-1)/(STEP))
/* 通用定义 */
#define NULL ((void*)0)
#define bool int
#define true 1
#define false 0
#define PG_SIZE 4096
#define UNUSED __attribute__ ((unused))

#endif // KERNEL_GLOBAL_H_
